﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Configuration;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;

namespace RRD2
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        Controler.Processor processor;
        Controler.Scanner scanner;
        ObservableCollection<Model.Message> scanned ;
        
        Model.SerialPort serialPort;
        DispatcherTimer dt;
        string gunNumber = string.Empty;
        string barcodeValue = string.Empty;
        string[] scanned;
        
        Model.Statement statement = new Model.Statement();
        SerialPort serial;
        private delegate void SetStatementDeleg(Model.Statement statement);
        
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Visualiser(Model.Statement statement)
        {
            
            switch (statement.Type)
            {
                case Model.StatementType.Exit:
                    Close();
                    //TextBlockMessage.Text = statement.Value;
                    if(statement.Value!=string.Empty)
                        TextBlockBarcode.Text = string.Format("{0} - {1}",statement.Barcode.Value,statement.Value);                    
                    break;
                case Model.StatementType.Error:
                    Grid.Background = Brushes.Red;
                    //TextBlockMessage.Text = statement.Value;
                    if (statement.Value != string.Empty)
                        TextBlockBarcode.Text = string.Format("{0} - {1}",statement.Barcode.Value,statement.Value);
                    scanned.Add(new RRD2.Model.Message()
                        {
                            Key = DateTime.Now,
                            MessageValue = string.Format("{0} {1} {2} {3}", DateTime.Now.ToLongTimeString(), statement.Barcode.Value, statement.Type, statement.Value)
                        });
                    //if (!string.IsNullOrEmpty(statement.TruckNumber))
                    //    TextBlockLorryNumber.Text = string.Format("{0}: {1}",ConfigurationManager.AppSettings["LorryNumberLabel"].ToString(), statement.TruckNumber);
                    //TextBlockErrorStatement.Text = statement.Value;
                    TextBlockMessage.Text = statement.Value;
                    break;
                case Model.StatementType.Message:
                    Grid.Background = Brushes.Green;                    
                    //TextBlockMessage.Text = statement.Value;
                    if (statement.Value != string.Empty)
                    {
                        TextBlockBarcode.Text = string.Format("{0} - {1}",statement.Barcode.Value,statement.Value);
                        scanned.Add(new RRD2.Model.Message()
                        {
                            Key = DateTime.Now,
                            MessageValue = string.Format("{0} {1}", DateTime.Now.ToLongTimeString(), statement.Barcode.Value)
                        });
                    }
                    //if (!string.IsNullOrEmpty(statement.TruckNumber))
                    //    TextBlockLorryNumber.Text = string.Format("{0}: {1}", ConfigurationManager.AppSettings["LorryNumberLabel"].ToString(), statement.TruckNumber);
                    
                    if (statement.Barcode.Type == Model.BarcodeType.Trolley)
                    {
                        //TextBoxFooter.Text += string.Format("{0} ; ", statement.Barcode.Value);
                        ListBoxTrolley.Items.Add(statement.Barcode.Value);
                        TextBlockListTrolleyHeader.Text = ConfigurationManager.AppSettings["TrolleyListHeader"].ToString();
                    }
                    //TextBlockErrorStatement.Text = string.Empty;
                    TextBlockMessage.Text = string.Empty;
                    
                    break;
                case Model.StatementType.Warning:
                    Grid.Background = Brushes.Orange;
                    //TextBlockMessage.Text = statement.Value;
                    TextBlockBarcode.Text = string.Format("{0} - {1}",statement.Barcode.Value,statement.Value);
                    //if (!string.IsNullOrEmpty(statement.TruckNumber))
                    //    TextBlockLorryNumber.Text = string.Format("{0}: {1}", ConfigurationManager.AppSettings["LorryNumberLabel"].ToString(), statement.TruckNumber);
                    scanned.Add(new RRD2.Model.Message()
                    {
                        Key=DateTime.Now,
                        MessageValue=string.Format("{0} {1} {2} {3}", DateTime.Now.ToLongTimeString(), statement.Barcode.Value, statement.Type,statement.Value)
                    });
                    
                    break;
                default:
                    
                    break;
            }

            if (processor.ShipmentStatus.Status.Equals(Model.ShipmentStatus.Open))
            {
                string tmp = TextBlockTimer.Text;
                TextBlockOpenTime.Text = string.Format("{0}: {1}",ConfigurationManager.AppSettings["OpenTimeLabel"].ToString(),processor.OpenedLorryTime.ToLongTimeString());
                TextBlockMessage.Text = ConfigurationManager.AppSettings["OpenTip"].ToString();
            }
            else if(processor.ShipmentStatus.Status.Equals(Model.ShipmentStatus.ReadyToOpen))
            {
                TextBlockTimer.Text = string.Empty;
                TextBlockOpenTime.Text = string.Empty;
                TextBlockMessage.Text = ConfigurationManager.AppSettings["ReadyToOpenTip"].ToString();
            }
            else if (processor.ShipmentStatus.Status.Equals(Model.ShipmentStatus.Close))
            {
                TextBlockTimer.Text = string.Empty;
                TextBlockOpenTime.Text = string.Empty;
                //TextBoxFooter.Text = string.Empty;
                ListBoxTrolley.Items.Clear();
                TextBlockListTrolleyHeader.Text = string.Empty;
                TextBlockMessage.Text = ConfigurationManager.AppSettings["CloseTip"].ToString();
            }
            else
            {
                //TextBlockTimer.Visibility = System.Windows.Visibility.Visible;
            }
            if (!string.IsNullOrEmpty(processor.Lorry.LorryName))
                TextBlockLorryNumber.Text = string.Format("{0}: {1}", ConfigurationManager.AppSettings["LorryNumberLabel"].ToString(), processor.Lorry.LorryName);
            else
                TextBlockLorryNumber.Text = string.Empty;
            ListBoxScannedBarcode.ItemsSource = scanned.OrderByDescending(n=>n.Key);
        }

        private void Window_TextInput(object sender, TextCompositionEventArgs e)
        {
            if (ConfigurationManager.AppSettings["ScannerType"].Equals("USB"))
            {
                string value = string.Empty;
                try
                {
                    if (e.Text.CompareTo('\r'.ToString()) == 0)
                    {
                        Visualiser(processor.GetScan(scanner.ReadBuffer(true)));
                    }
                    else
                    {
                        scanner.WriteBuffer(e.Text);
                    }
                }
                catch (Exception ex)
                {
                    DAL.Logger.WriteException(ex);
                }
            }
        }

        private void Window_Closing_1(object sender, CancelEventArgs e)
        {
            serial.Close();
        }

        private void Window_Loaded_1(object sender, RoutedEventArgs e)
        {
            processor = new Controler.Processor();
            scanned = new ObservableCollection<Model.Message>();
            scanned.Add(new RRD2.Model.Message()
            {
                Key = DateTime.Now,
                MessageValue = string.Format("{0} {1}", DateTime.Now.ToLongTimeString(), ConfigurationManager.AppSettings["ApplicationStartMessage"].ToString())
            });
            if (ConfigurationManager.AppSettings["ScannerType"].Equals("RS232"))
            {
                RS232Reader();
            }
            if (ConfigurationManager.AppSettings["ScannerType"].Equals("USB"))
            {
                scanner = new Controler.Scanner();
            }
            
            TextBlockWorkstation.Text = Environment.MachineName;
            Visualiser(new Model.Statement() { Value=string.Empty,Type = Model.StatementType.Message , Barcode=new Model.Barcode()});
            var title = ConfigurationManager.AppSettings["ApplicationName"].ToString();
            Version v = new Version();
            var version = string.Format("{0}.{1}.{2}", v.Major, v.Minor, v.Revision);
            this.Title = string.Format("{0} v.{1}", title, version);
            TextBlockLorryNumber.Text = string.Empty;
            Clock();
        }
        
        private void Clock()
        {
            dt = new DispatcherTimer();
            dt.Tick += dt_Tick;
            dt.Interval = new TimeSpan(1000);
            dt.Start();
        }

        void dt_Tick(object sender, EventArgs e)
        {
            TextBlockClock.Text = string.Format("{0}\r{1}",new DateTime(DateTime.Now.Ticks).ToString("dd-MM-yyyy"),new DateTime(DateTime.Now.Ticks).ToString("HH:mm:ss"));
            if (!processor.OpenedLorryTime.Equals(new DateTime()))
            {
                TimeSpan ts = DateTime.Now - processor.OpenedLorryTime;
                TextBlockTimer.Text = string.Format("{0}: {1}",ConfigurationManager.AppSettings["TimerLabel"].ToString(),new DateTime(ts.Ticks).ToString("HH:mm:ss"));
                TextBlockOpenTime.Text = string.Format("{0}: {1}",ConfigurationManager.AppSettings["OpenTimeLabel"].ToString(),processor.OpenedLorryTime.ToLongTimeString());
            }
        }

        private void RS232Reader()
        {
            try
            {
                serialPort = new Model.SerialPort();
                serial = new SerialPort();
                serial.PortName = serialPort.GetPortName(ConfigurationManager.AppSettings["PortName"]);
                serial.BaudRate = serialPort.GetBaudRate(ConfigurationManager.AppSettings["BaudRate"]);
                serial.Parity = serialPort.GetParity(ConfigurationManager.AppSettings["Parity"]);
                serial.StopBits = serialPort.StopBits(ConfigurationManager.AppSettings["StopBits"]);
                serial.DataBits = serialPort.GetDataBits(ConfigurationManager.AppSettings["DataBits"]);
                serial.DataReceived += serial_DataReceived;
                //serial.ReadTimeout = 50;
                serial.Open();
            }
            catch(Exception ex)
            {
                DAL.Logger.WriteException(ex);
                MessageBox.Show(ex.Message);
            }
        }

        void serial_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            try
            {                
                barcodeValue = serial.ReadLine().TrimEnd('\r');
                scanned = barcodeValue.Split(';');
                if (barcodeValue.Length > 1)
                {
                    barcodeValue = scanned[scanned.Length - 1];
                    gunNumber = scanned[0];
                }
                else
                {
                    barcodeValue = scanned[barcodeValue.Length - 1];
                    gunNumber = "0000";
                }
                statement = processor.GetScan(barcodeValue);

                if (statement.Type.Equals(Model.StatementType.Message) || statement.Type.Equals(Model.StatementType.Warning))
                    serial.Write(gunNumber+";" + (char)27 + "[3q" + (char)13);
                else
                    serial.Write(gunNumber + ";" + (char)27 + "[6q" + (char)27 + "[5q" + (char)27 + "[0q" + (char)27 + "[5q" + (char)27 + "[0q" + (char)27 + "[7q" + (char)13);
                Dispatcher.BeginInvoke(new SetStatementDeleg(Visualiser), new object[] { statement });
            }
            catch (Exception ex)
            {
                DAL.Logger.WriteException(ex);
                MessageBox.Show(ex.Message);
            }
        }
    }
}
